package com.github.iogogogo.kafka.manager;

import io.vavr.Tuple3;
import org.apache.kafka.clients.admin.*;
import org.apache.kafka.clients.consumer.OffsetAndMetadata;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.config.ConfigResource;

import java.util.*;

/**
 * The interface Kafka service.
 */
public interface KafkaService {

    /**
     * The constant OFFSET_RESET_LATEST.
     */
    String OFFSET_RESET_LATEST = "latest";
    /**
     * The constant OFFSET_RESET_EARLIEST.
     */
    String OFFSET_RESET_EARLIEST = "earliest";

    /**
     * List topic set.
     *
     * @return the set
     */
    Set<String> listTopic();

    /**
     * Create topic boolean.
     *
     * @param topic             the topic
     * @param numPartitions     the num partitions
     * @param replicationFactor the replication factor
     * @return the boolean
     */
    boolean createTopic(String topic, int numPartitions, short replicationFactor);

    /**
     * Create topic boolean.
     *
     * @param newTopics the new topics
     * @return the boolean
     */
    boolean createTopic(Collection<NewTopic> newTopics);

    /**
     * Delete topics boolean.
     *
     * @param topics the topics
     * @return the boolean
     */
    boolean deleteTopics(Collection<String> topics);

    /**
     * Describe cluster map.
     *
     * @return the map
     */
    Map<String, Object> describeCluster();

    /**
     * Describe configs map.
     *
     * @param resources the resources
     * @return the map
     */
    Map<ConfigResource, Config> describeConfigs(Collection<ConfigResource> resources);

    /**
     * Alter configs boolean.
     *
     * @param configs the configs
     * @return the boolean
     */
    boolean alterConfigs(Map<ConfigResource, Collection<AlterConfigOp>> configs);

    /**
     * List consumer groups list.
     *
     * @return the list
     */
    List<ConsumerGroupListing> listConsumerGroups();

    /**
     * List consumer group offsets map.
     *
     * @param groupId the group id
     * @param options the options
     * @return the map
     */
    Map<TopicPartition, OffsetAndMetadata> listConsumerGroupOffsets(String groupId, ListConsumerGroupOffsetsOptions options);

    /**
     * Delete consumer groups boolean.
     *
     * @param groupIds the group ids
     * @return the boolean
     */
    boolean deleteConsumerGroups(Collection<String> groupIds);

    /**
     * List offsets map.
     *
     * @param topicPartitionOffsets the topic partition offsets
     * @return the map
     */
    Map<TopicPartition, ListOffsetsResult.ListOffsetsResultInfo> listOffsets(Map<TopicPartition, OffsetSpec> topicPartitionOffsets);

    /**
     * Describe topics map.
     *
     * @param topicNames the topic names
     * @return the map
     */
    Map<String, TopicDescription> describeTopics(Collection<String> topicNames);

    /**
     * Describe consumer groups map.
     *
     * @param groupIds the group ids
     * @return the map
     */
    Map<String, ConsumerGroupDescription> describeConsumerGroups(Collection<String> groupIds);

    /**
     * Describe topics map.
     *
     * @param topicNames the topic names
     * @param options    the options
     * @return the map
     */
    Map<String, TopicDescription> describeTopics(Collection<String> topicNames, DescribeTopicsOptions options);

    /**
     * Exists topic boolean.
     *
     * @param topic the topic
     * @return the boolean
     */
    boolean existsTopic(String topic);

    /**
     * Topic groups list.
     *
     * @param topic the topic
     * @return the list
     */
    List<String> topicGroups(String topic);

    /**
     * Topic partition offset long.
     * <p>
     * producer 的生产总量
     *
     * @param topic      the topic
     * @param groupId    the group id
     * @param reset      the reset
     * @param autoCommit the auto commit
     * @return the long
     */
    Long topicEndOffset(String topic, String groupId, String reset, boolean autoCommit);

    /**
     * Topic partition end offset map.
     *
     * @param topic      the topic
     * @param groupId    the group id
     * @param reset      the reset
     * @param autoCommit the auto commit
     * @return the map
     */
    Map<TopicPartition, Long> topicPartitionEndOffset(String topic, String groupId, String reset, boolean autoCommit);

    /**
     * Topic consumer offset long.
     * <p>
     * consumer的消费总量
     *
     * @param topic      the topic
     * @param groupId    the group id
     * @param reset      the reset
     * @param autoCommit the auto commit
     * @return the long
     */
    Long topicCurrentOffset(String topic, String groupId, String reset, boolean autoCommit);

    /**
     * Topic consumer current offset map.
     *
     * @param topic      the topic
     * @param groupId    the group id
     * @param reset      the reset
     * @param autoCommit the auto commit
     * @return the map
     */
    Map<TopicPartition, Long> topicPartitionCurrentOffset(String topic, String groupId, String reset, boolean autoCommit);

    /**
     * Topic lag long.
     *
     * @param topic      the topic
     * @param groupId    the group id
     * @param reset      the reset
     * @param autoCommit the auto commit
     * @return the long
     */
    Tuple3<Long, Long, Long> topicLag(String topic, String groupId, String reset, boolean autoCommit);


    /**
     * Offset consumer object.
     *
     * @param topic      the topic
     * @param groupId    the group id
     * @param reset      the reset
     * @param autoCommit the auto commit
     * @return the object
     */
    List<Object> toLatestConsuming(String topic, String groupId, String reset, boolean autoCommit);

    /**
     * Offset consumer object.
     *
     * @param topic       the topic
     * @param groupId     the group id
     * @param reset       the reset
     * @param timeoutSize the timeout size
     * @param autoCommit  the auto commit
     * @return the object
     */
    List<Object> toLatestConsuming(String topic, String groupId, String reset, int timeoutSize, boolean autoCommit);

    /**
     * Uuid string.
     *
     * @return the string
     */
    default String uuid() {
        return UUID.randomUUID().toString().replace("-", "").toLowerCase(Locale.ROOT);
    }
}
